{

VERSION 1.0, Ivan V. Minin 2008

http://code.google.com/p/matcalc

Copyright notice:
----------------

matrix algebra calculator sourcecode for Delphi
Copyright (C) Ivan V. Minin, 2008

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

}
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, Grids, linalg,strutils, jpeg, ExtCtrls;

type
  TForm1 = class(TForm)
    MatrixAbox: TGroupBox;
    Open2A: TButton;
    SaveA: TButton;
    ZeroA: TButton;
    ARowCount: TEdit;
    AColCount: TEdit;
    Label4: TLabel;
    MatrixA: TStringGrid;
    MatrixBbox: TGroupBox;
    BColCount: TEdit;
    BRowCount: TEdit;
    Label2: TLabel;
    Label3: TLabel;
    MatrixB: TStringGrid;
    OpenB: TButton;
    SaveB: TButton;
    ZeroB: TButton;
    ResultBox: TGroupBox;
    Sum: TButton;
    Subtract: TButton;
    Multyply: TButton;
    Label7: TLabel;
    ResCol: TEdit;
    Label8: TLabel;
    ResRow: TEdit;
    Label9: TLabel;
    ResMatrix: TStringGrid;
    OpenDialog: TOpenDialog;
    SaveDialog: TSaveDialog;
    power: TButton;
    power_koeff: TEdit;
    stepen: TLabel;
    RandB: TButton;
    RandA: TButton;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
    procedure BColCountChange(Sender: TObject);
    procedure BRowCountChange(Sender: TObject);
    procedure RandAClick(Sender: TObject);
    procedure RandBClick(Sender: TObject);
    procedure OnesBClick(Sender: TObject);
    procedure OnesAClick(Sender: TObject);
    procedure powerClick(Sender: TObject);
    procedure power_koeffKeyPress(Sender: TObject; var Key: Char);
    procedure BColCountKeyPress(Sender: TObject; var Key: Char);
    procedure AColCountChange(Sender: TObject);
    procedure ARowCountChange(Sender: TObject);
    procedure BRowCountKeyPress(Sender: TObject; var Key: Char);
    procedure AColCountKeyPress(Sender: TObject; var Key: Char);
    procedure ARowCountKeyPress(Sender: TObject; var Key: Char);
    procedure MultyplyClick(Sender: TObject);
    procedure SubtractClick(Sender: TObject);
    procedure SumClick(Sender: TObject);
    procedure BtoAClick(Sender: TObject);
    procedure ReplaceABClick(Sender: TObject);
    procedure AtoBClick(Sender: TObject);
    procedure TransBClick(Sender: TObject);
    procedure TransAClick(Sender: TObject);
    procedure SaveBClick(Sender: TObject);
    procedure OpenBClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ZeroBClick(Sender: TObject);
    procedure ZeroAClick(Sender: TObject);
    procedure MatrixBKeyPress(Sender: TObject; var Key: Char);
    procedure SaveAClick(Sender: TObject);
    procedure Open2AClick(Sender: TObject);
    procedure MatrixAKeyPress(Sender: TObject; var Key: Char);
    function MatrixFromGrid(Grid: TStringGrid):TMatrix;
   procedure Matrix2Grid(Matrix: TMatrix; Grid: TStringGrid);
   procedure Zero(grid: TStringGrid);
   procedure save_dial(grid: TStringGrid);
   procedure Open_Dial(grid: TStringGrid);
   procedure transp(grid: TStringGrid);
   procedure rand(grid: TStringGrid);
   procedure numbering(Grid: TStringGrid);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  act_type,text_1: string;
  act_i,act_j: integer;

implementation

{$R *.dfm}
procedure TForm1.rand(grid: TStringGrid);
var
i,j,k: integer;
begin
Randomize;
for i := 1 to grid.RowCount - 1 do
for j := 1 to grid.ColCount - 1 do
  begin
    k:=Random(21)-10;
     grid.Cells[j,i]:=IntToStr(k);
  end;
end;
procedure TForm1.numbering(grid: TStringGrid);
var
i,j: integer;
begin
  for j := 0 to Grid.ColCount - 1 do
    begin
      Grid.Cells[j,0]:=IntToStr(j);
    end;
  for i := 0 to Grid.RowCount - 1 do
    begin
      Grid.Cells[0,i]:=inttostr(i);
    end;
end;

procedure TForm1.transp(grid: TStringGrid);
var
matrix: TMatrix;
size: TSize;
begin
   matrix:=MatrixFromGrid(grid);
   size:=SizeOfMatrix(matrix);
   //ShowMessage(inttostr(size.Rows));
   //ShowMessage(inttostr(size.cols));
   matrix:=Transpose(matrix);
   Zero(grid);
   Matrix2Grid(matrix,grid);
end;

procedure TForm1.Zero(grid: TStringGrid);
var
Matrix: TMatrix;
j: integer;
begin
  Matrix:=ZeroMatrix(SetSize(grid.RowCount-1,grid.ColCount-1));
  Matrix2Grid(Matrix,grid);
  for j:=0 to grid.ColCount-1 do grid.ColWidths[j]:=grid.DefaultColWidth;    
end;


procedure TForm1.ZeroAClick(Sender: TObject);
begin
Zero(MatrixA);
end;

procedure TForm1.ZeroBClick(Sender: TObject);
begin
zero(MatrixB);
end;

procedure TForm1.Matrix2Grid(Matrix: TMatrix; Grid: TStringGrid);
var
i,j: Integer;
tw: integer;
stroka: String;
begin
  Grid.RowCount:=SizeOfMatrix(Matrix).Rows+1;
  Grid.ColCount:=SizeOfMatrix(Matrix).Cols+1;
  for i := 0 to SizeOfMatrix(Matrix).Rows-1 do
  for j := 0 to SizeOfMatrix(Matrix).Cols-1 do
  begin
    Grid.Cells[j+1,i+1]:= FloatToStr(Matrix[i,j]);
    stroka:=FloatToStr(Matrix[i,j]);
//    stroka:=G.Cells[MatrixA.Col, MatrixA.Row];
    tw:=length(stroka);
    if (Grid.ColWidths[j+1]<tw*10)then Grid.ColWidths[j+1]:=tw*7+15;
//    Grid.ColWidths[j+1]:=tw;
  end;
  numbering(Grid);
end;

procedure TForm1.MatrixAKeyPress(Sender: TObject; var Key: Char);
var
stroka: String;
tw: integer;
begin
case Key of
#8,'0'..'9' : ;
'.',',':
begin
stroka:=MatrixA.Cells[MatrixA.Col, MatrixA.Row];
if not (Key=DecimalSeparator) then Key := DecimalSeparator;
if Pos(DecimalSeparator,stroka)<>0
then Key := Chr(0);
end;
'-':
begin
if pos('-',MatrixA.Cells[MatrixA.Col, MatrixA.Row])=0 then
MatrixA.Cells[MatrixA.Col, MatrixA.Row]:='-'+MatrixA.Cells[MatrixA.Col, MatrixA.Row];
Key := Chr(0);
end;
else
key := Chr(0);
end;
Zero(ResMatrix);
{//stroka:=MatrixA.Cells[MatrixA.Col, MatrixA.Row];
//tw:=MatrixA.Canvas.TextWidth(stroka);
for i:=1 to MatrixA.RowCount-1 do
for j:=1 to MatrixA.ColCount-1 do
begin                                           }
stroka:=MatrixA.Cells[MatrixA.Col, MatrixA.Row];
tw:=length(stroka);
if (MatrixA.ColWidths[MatrixA.Col]<tw*10)then MatrixA.ColWidths[MatrixA.Col]:=tw*7+15;
//end;
end;

procedure TForm1.MatrixBKeyPress(Sender: TObject; var Key: Char);
var
stroka: String;
tw:integer;
begin
case Key of
#8,'0'..'9' : ;
'.',',':
begin
stroka:=MatrixB.Cells[MatrixB.Col, MatrixB.Row];
if not (Key=DecimalSeparator) then Key := DecimalSeparator;
if Pos(DecimalSeparator,stroka)<>0
then Key := Chr(0);
end;
'-':
begin
if pos('-',MatrixB.Cells[MatrixB.Col, MatrixB.Row])=0 then
MatrixB.Cells[MatrixB.Col, MatrixB.Row]:='-'+MatrixB.Cells[MatrixB.Col, MatrixB.Row];
Key := Chr(0);
end;
else
key := Chr(0);
end;
Zero(ResMatrix);
stroka:=MatrixB.Cells[MatrixB.Col, MatrixB.Row];
tw:=length(stroka);
if (MatrixB.ColWidths[MatrixB.Col]<tw*10)then MatrixB.ColWidths[MatrixB.Col]:=tw*11;

end;

function TForm1.MatrixFromGrid(Grid: TStringGrid):TMatrix;
var
i,j: integer;
begin
    Result:=NewMatrix(SetSize(Grid.RowCount-1, Grid.ColCount-1));
   for i := 1 to  (Grid.RowCount-1) do
   for j := 1 to  (Grid.ColCount-1) do
   begin
   if length(Grid.Cells[j,i])=0 then Grid.Cells[j,i]:='0';
     Result[i-1,j-1]:=StrToFloat(Grid.Cells[j,i]);
end;
end;

procedure TForm1.MultyplyClick(Sender: TObject);
var
m1,m2,m3: TMatrix;
begin
if MatrixA.ColCount<>MatrixB.RowCount then begin showMessage('������ ����� �������'); exit; end else
m1:=MatrixFromGrid(MatrixA);
m2:=MatrixFromGrid(MatrixB);
m3:=Linalg.Multiply(m1,m2);
Matrix2Grid(m3,ResMatrix);
ResRow.Text:=IntToStr(ResMatrix.RowCount-1);
ResCol.Text:=IntToStr(ResMatrix.ColCount-1);
end;

procedure TForm1.OnesAClick(Sender: TObject);
var
m1: TMatrix;
begin
m1:=Eye(SetSize(MatrixA.RowCount-1,MatrixA.ColCount-1));
Matrix2Grid(m1,MatrixA);
end;

procedure TForm1.OnesBClick(Sender: TObject);
var
m1: TMatrix;
begin
m1:=Eye(SetSize(MatrixB.RowCount-1,MatrixB.ColCount-1));
Matrix2Grid(m1,MatrixB);
end;

procedure TForm1.Open2AClick(Sender: TObject);
begin
Open_Dial(MatrixA);
ARowCount.Text:=IntToStr(MatrixA.RowCount-1);
AColCount.Text:=IntToStr(MatrixA.ColCount-1);
end;


procedure TForm1.OpenBClick(Sender: TObject);
begin
Open_Dial(MatrixB);
BRowCount.Text:=IntToStr(MatrixB.RowCount-1);
BColCount.Text:=IntToStr(MatrixB.ColCount-1);
end;

procedure TForm1.save_dial(grid: TStringGrid);
var
matrix: TMatrix;
begin
  if (SaveDialog.Execute) then
  begin
  matrix:=MatrixFromGrid(grid);
  SaveMatrixToFile(matrix,SaveDialog.FileName);
  end;
end;

procedure TForm1.SubtractClick(Sender: TObject);
var
m1,m2,m3: TMatrix;
begin
if (MatrixA.RowCount<>MatrixB.RowCount) and (MatrixA.ColCount<>MatrixB.ColCount) then showMessage('������ ����� �������') else
m1:=MatrixFromGrid(MatrixA);
m2:=MatrixFromGrid(MatrixB);
m3:=linalg.Subtract(m1,m2);
Matrix2Grid(m3,ResMatrix);
ResRow.Text:=IntToStr(ResMatrix.RowCount-1);
ResCol.Text:=IntToStr(ResMatrix.ColCount-1);
end;

procedure TForm1.SumClick(Sender: TObject);
var
m1,m2,m3: TMatrix;
begin
if (MatrixA.RowCount<>MatrixB.RowCount) and (MatrixA.ColCount<>MatrixB.ColCount) then showMessage('������ ����� �������') else
m1:=MatrixFromGrid(MatrixA);
m2:=MatrixFromGrid(MatrixB);
m3:=Add(m1,m2);
Matrix2Grid(m3,ResMatrix);
ResRow.Text:=IntToStr(ResMatrix.RowCount-1);
ResCol.Text:=IntToStr(ResMatrix.ColCount-1);
end;

procedure TForm1.TransAClick(Sender: TObject);
begin
transp(MatrixA);
end;

procedure TForm1.TransBClick(Sender: TObject);
begin
transp(MatrixB);
end;

procedure TForm1.Open_Dial(grid: TStringGrid);
var
matrix: TMatrix;
Size: TSize;
begin
  if OpenDialog.Execute then
  begin
       matrix:=LoadMatrixFromFile(OpenDialog.FileName);
       Size:=SizeOfMatrix(matrix);
       if (Size.Rows=grid.RowCount-1) and (Size.Cols=grid.ColCount-1) then Matrix2Grid(matrix,grid) else showMessage('�������������� �������� ����������� ������� � �������');
  end;
end;

procedure TForm1.powerClick(Sender: TObject);
var
m1,m2: TMatrix;
i,st: Integer;
begin
if length(power_koeff.Text)<>0 then
begin
st:=StrToInt(power_koeff.Text);
m1:=MatrixFromGrid(MatrixA);
m2:=MatrixFromGrid(MatrixA);
for I := 2 to st do
begin
  m1:=Multiply(m1,m2);
end;
Matrix2Grid(m1,ResMatrix);
ResRow.Text:=IntToStr(ResMatrix.RowCount-1);
ResCol.Text:=IntToStr(ResMatrix.ColCount-1);
end
else showMessage('������� �������');
end;

procedure TForm1.power_koeffKeyPress(Sender: TObject; var Key: Char);
begin
if not (key in [#8,'0'..'9']) then Key:=chr(0);
end;

procedure TForm1.RandAClick(Sender: TObject);
begin
rand(MatrixA);
end;

procedure TForm1.RandBClick(Sender: TObject);
begin
rand(MatrixB);
end;

procedure TForm1.ReplaceABClick(Sender: TObject);
var
m1,m2: TMatrix;
begin
m1:=MatrixFromGrid(MatrixA);
m2:=MatrixFromGrid(MatrixB);
Matrix2Grid(m2,MatrixA);
Matrix2Grid(m1,MatrixB);
end;

procedure TForm1.SaveAClick(Sender: TObject);
begin
save_dial(MatrixA);
end;

procedure TForm1.SaveBClick(Sender: TObject);
begin
save_dial(MatrixB);
end;

procedure TForm1.AColCountChange(Sender: TObject);
begin
if not (AcolCount.Text='') and (AcolCount.Text<>'0') then
begin
  MatrixA.colCount:=StrToInt(Acolcount.Text)+1;
  ResMatrix.ColCount:=2;
  ResMatrix.RowCount:=2;
    Zero(ResMatrix);
    if (act_type='add') or (act_type='substract') then
  begin
    MatrixB.ColCount:=strToInt(AColcount.Text)+1;
    BColCount.Text:=AcolCount.Text;
    Zero(MatrixA);
    Zero(MatrixB);
    Zero(ResMatrix);
  end
    else if (act_type='multiply') then
       begin
         MatrixB.RowCount:=strtoint(AColCount.Text)+1;
         Zero(MatrixA);
         Zero(MatrixB);
         Zero(ResMatrix);
         BRowCount.Text:=AColCount.Text;
       end
         else if act_type='power' then
       begin
         Zero(MatrixA);
         Zero(ResMatrix);
         ARowCount.Text:=AColCount.Text;
       end;
end;
numbering(MatrixA);
numbering(MatrixB);
end;

procedure TForm1.AColCountKeyPress(Sender: TObject; var Key: Char);
begin
  if not (key in [#8,'0'..'9'])  then Key:=chr(0)
end;

procedure TForm1.ARowCountChange(Sender: TObject);
begin
if not (ArowCount.Text='') and (ArowCount.Text<>'0') then
begin
  MatrixA.RowCount:=StrToInt(Arowcount.Text)+1;
  ResMatrix.ColCount:=2;
  ResMatrix.RowCount:=2;
    Zero(ResMatrix);
  if (act_type='add') or (act_type='substract') then
  begin
    MatrixB.RowCount:=strToInt(Arowcount.Text)+1;
    BRowCount.Text:=ARowCount.Text;
    Zero(MatrixA);
    Zero(MatrixB);
    Zero(ResMatrix);
  end
  else if (act_type='multiply') then
       begin
         //MatrixB.ColCount:=strtoint(ARowCount.Text)+1;
         Zero(MatrixA);
         Zero(MatrixB);

         //BColCount.Text:=ARowCount.Text;
       end
  else if act_type='power' then
       begin
         Zero(MatrixA);
         Zero(ResMatrix);
         AColCount.Text:=ARowCount.Text;
       end;
end;
numbering(MatrixA);
numbering(MatrixB);
end;


procedure TForm1.ARowCountKeyPress(Sender: TObject; var Key: Char);
begin
  if not (key in [#8,'0'..'9'])  then Key:=chr(0)
  
end;

procedure TForm1.AtoBClick(Sender: TObject);
var
m1: TMatrix;
begin
m1:=MatrixFromGrid(MatrixA);
Zero(MatrixA);
Matrix2Grid(m1,MatrixB);
end;


procedure TForm1.BColCountChange(Sender: TObject);
begin
if not (BcolCount.Text='') and (BcolCount.Text<>'0') then
begin
  MatrixB.colCount:=StrToInt(Bcolcount.Text)+1;
  ResMatrix.ColCount:=2;
  ResMatrix.RowCount:=2;
  Zero(ResMatrix);
    if (act_type='add') or (act_type='substract') then
  begin
    MatrixA.ColCount:=strToInt(BColcount.Text)+1;
    AColCount.Text:=BcolCount.Text;
    Zero(MatrixA);
    Zero(MatrixB);
//    Zero(ResMatrix);
  end
    else if (act_type='multiply') then
       begin
         //MatrixA.RowCount:=strtoint(BColCount.Text)+1;
         //ARowCount.Text:=BColCount.Text;
         Zero(MatrixB);
         Zero(MatrixA);
//         Zero(ResMatrix);
       end;
end;
numbering(MatrixA);
numbering(MatrixB);
end;

procedure TForm1.BColCountKeyPress(Sender: TObject; var Key: Char);
begin
   if not (key in [#8,'0'..'9'])  then Key:=chr(0);
end;

procedure TForm1.BRowCountChange(Sender: TObject);
begin
if not (BrowCount.Text='') and (BrowCount.Text<>'0') then
begin
  MatrixB.RowCount:=StrToInt(Browcount.Text)+1;
  ResMatrix.ColCount:=2;
  ResMatrix.RowCount:=2;
    Zero(ResMatrix);
  if (act_type='add') or (act_type='substract') then
  begin
    MatrixA.RowCount:=strToInt(Browcount.Text)+1;
    ARowCount.Text:=BRowCount.Text;
    Zero(MatrixA);
    Zero(MatrixB);
    Zero(ResMatrix);
  end
  else if (act_type='multiply') then
       begin
         MatrixA.ColCount:=strtoint(BRowCount.Text)+1;
         Zero(MatrixA);
         Zero(MatrixB);
         Zero(ResMatrix);
         AColCount.Text:=BRowCount.Text;
       end;
end;
numbering(MatrixA);
numbering(MatrixB);
end;

procedure TForm1.BRowCountKeyPress(Sender: TObject; var Key: Char);
begin
  if not (key in [#8,'0'..'9'])  then Key:=chr(0);
end;

procedure TForm1.BtoAClick(Sender: TObject);
var
m1: TMatrix;
begin
m1:=MatrixFromGrid(MatrixB);
Zero(MatrixB);
Matrix2Grid(m1,MatrixA);
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
save_dial(ResMatrix);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
numbering(MatrixA);
numbering(MatrixB);
numbering(ResMatrix);
Zero(MatrixA);
Zero(MatrixB);
Zero(ResMatrix);
end;

end.
